----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    15:29:48 03/22/2013 
-- Design Name: 
-- Module Name:    FAT32 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
-- library UNISIM;
-- use UNISIM.VComponents.all;

-- modify version
entity FAT32_UserCtrl is
    Port 
	( 
		Rst 			: in  STD_LOGIC;
        Clk 			: in  STD_LOGIC;
           
		FmtReq 			: in  STD_LOGIC;
		
		-- SataUser interface
		SataBusy				: in	std_logic;							-- Busy
		SataCmd					: out	std_logic;							-- '0': Write, '1': Read
		SataCmdReq				: out	std_logic;							-- Command Request
		SataAddr				: out	std_logic_vector( 47 downto 0 );	-- Sector Address
		SataLength				: out	std_logic_vector( 16 downto 0 );	-- Sector length (1-65536)
		
		-- SataFifo interface
		WrFfAFull				: in	std_logic;							-- Fifo almost full
		WrFfWrEn				: out	std_logic;							-- Fifo write enable
		WrFfWrData				: out	std_logic_vector( 31 downto 0 )	-- Fifo write data	
	);
end FAT32_UserCtrl;

architecture Behavioral of FAT32_UserCtrl is

----------------------------------------------------------------------------------
-- Signal declaration
----------------------------------------------------------------------------------	
	
-- State machine
	Type	FmtCtrlStateType is
							(
								stIdle,
								stWrPrep,
								stWrReq,
								stWrStream,
								stWrWt,
								stCntFmtChk,
								stEnd
							);
	signal	rFmtState	: FmtCtrlStateType;	
	
	-- SataUser interface
	signal rSataCmdReq 		:   STD_LOGIC;
    signal rSataCmd 		:   STD_LOGIC;
    signal rSataAddr 		:   STD_LOGIC_VECTOR (47 downto 0);
    signal rSataLength 		:   STD_LOGIC_VECTOR (16 downto 0);
	
	-- SataFifo interface
	signal rWrFfWrEn 		:  STD_LOGIC;
	signal rWrFfDataSelect	:  STD_LOGIC;
	signal rWrFfWrData		:  STD_LOGIC_VECTOR (31 downto 0);
	
	-- Ram
	signal rRAMOffset		:  STD_LOGIC_VECTOR (8 downto 0);
	signal rRAMAddr			:  STD_LOGIC_VECTOR (8 downto 0);
	signal rRAMWrEn			:  STD_LOGIC;
	signal rRAMDin			:  STD_LOGIC_VECTOR (31 downto 0);
	signal rRAMDout			:  STD_LOGIC_VECTOR (31 downto 0);
	
	type array512ofu32 is array (0 to 511) of std_logic_vector( 31 downto 0 );
	
    signal RamMem : array512ofu32 :=
	(
--		 [1:0]        [3:2] 	   [5:4]        [7:6]        [9:8]        [11:10]      [13:12]      [15:14]
		x"2000044A", x"00100000", x"00000000", x"0000003F", x"00000000", x"31303230", x"392F2F30", x"2D533234", 
--       [17:16]      [19:18]      [21:20]      [23:22]      [25:24]      [27:26]      [29:28]      [31:30]
		x"3020322D", x"20202020", x"00000000", x"41300000", x"3230372E", x"41434541", x"4C4C4849", x"20534553", 
--       [33:32]      [35:34]      [37:36]      [39:38]      [41:40]      [43:42]      [45:44]      [47:46]
		x"41204154", x"534B4449", x"20200D0A", x"20202020", x"20202020", x"20202020", x"20202020", x"80012020", 
--       [49:48]      [51:50]      [53:52]      [55:54]      [57:56]      [59:58]      [61:60]      [63:62]
		x"0F000000", x"02004000", x"00070200", x"00102000", x"0000003F", x"0101007E", x"007E0000", x"04070000", 
--       [65:64]      [67:66]      [69:68]      [71:70]      [73:72]      [75:74]      [77:76]      [79:78]
		x"00780003", x"00780078", x"00000078", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [81:80]      [83:82]      [85:84]      [87:86]      [89:88]      [91:90]      [93:92]      [95:94]
		x"000000FE", x"44000000", x"00004000", x"40000400", x"0000203F", x"00000000", x"00000000", x"00000000", 
--       [97:96]      [99:98]      [101:100]    [103:102]    [105:104]    [107:106]    [109:108]    [111:110]
		x"00000000", x"00000000", x"007E0000", x"00000000", x"00000000", x"00004000", x"00000000", x"00000000", 
--       [113:112]    [115:114]    [117:116]    [119:118]    [121:120]    [123:122]    [125:124]    [127:126]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [129:128]    [131:130]    [133:132]    [135:134]    [137:136]    [139:138]    [141:140]    [143:142]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [145:144]    [147:146]    [149:148]    [151:150]    [153:152]    [155:154]    [157:156]    [159:158]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [161:160]    [163:162]    [165:164]    [167:166]    [169:168]    [171:170]    [173:172]    [175:174]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [177:176]    [179:178]    [181:180]    [183:182]    [185:184]    [187:186]    [189:188]    [191:190]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [193:192]    [195:194]    [197:196]    [199:198]    [201:200]    [203:202]    [205:204]    [207:206]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [209:208]    [211:210]    [213:212]    [215:214]    [217:216]    [219:218]    [221:220]    [223:222]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [225:224]    [227:226]    [229:228]    [231:230]    [233:232]    [235:234]    [237:236]    [239:238]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [241:240]    [243:242]    [245:244]    [247:246]    [249:248]    [251:250]    [253:252]    [255:254]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000",
--		 [1:0]        [3:2] 	   [5:4]        [7:6]        [9:8]        [11:10]      [13:12]      [15:14]
		x"2000044A", x"00100000", x"00000000", x"0000003F", x"00000000", x"31303230", x"392F2F30", x"2D533234", 
--       [17:16]      [19:18]      [21:20]      [23:22]      [25:24]      [27:26]      [29:28]      [31:30]
		x"3020322D", x"20202020", x"00000000", x"41300000", x"3230372E", x"41434541", x"4C4C4849", x"20534553", 
--       [33:32]      [35:34]      [37:36]      [39:38]      [41:40]      [43:42]      [45:44]      [47:46]
		x"41204154", x"534B4449", x"20200D0A", x"20202020", x"20202020", x"20202020", x"20202020", x"80012020", 
--       [49:48]      [51:50]      [53:52]      [55:54]      [57:56]      [59:58]      [61:60]      [63:62]
		x"0F000000", x"02004000", x"00070200", x"00102000", x"0000003F", x"0101007E", x"007E0000", x"04070000", 
--       [65:64]      [67:66]      [69:68]      [71:70]      [73:72]      [75:74]      [77:76]      [79:78]
		x"00780003", x"00780078", x"00000078", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [81:80]      [83:82]      [85:84]      [87:86]      [89:88]      [91:90]      [93:92]      [95:94]
		x"000000FE", x"44000000", x"00004000", x"40000400", x"0000203F", x"00000000", x"00000000", x"00000000", 
--       [97:96]      [99:98]      [101:100]    [103:102]    [105:104]    [107:106]    [109:108]    [111:110]
		x"00000000", x"00000000", x"007E0000", x"00000000", x"00000000", x"00004000", x"00000000", x"00000000", 
--       [113:112]    [115:114]    [117:116]    [119:118]    [121:120]    [123:122]    [125:124]    [127:126]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [129:128]    [131:130]    [133:132]    [135:134]    [137:136]    [139:138]    [141:140]    [143:142]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [145:144]    [147:146]    [149:148]    [151:150]    [153:152]    [155:154]    [157:156]    [159:158]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [161:160]    [163:162]    [165:164]    [167:166]    [169:168]    [171:170]    [173:172]    [175:174]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [177:176]    [179:178]    [181:180]    [183:182]    [185:184]    [187:186]    [189:188]    [191:190]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [193:192]    [195:194]    [197:196]    [199:198]    [201:200]    [203:202]    [205:204]    [207:206]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [209:208]    [211:210]    [213:212]    [215:214]    [217:216]    [219:218]    [221:220]    [223:222]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [225:224]    [227:226]    [229:228]    [231:230]    [233:232]    [235:234]    [237:236]    [239:238]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [241:240]    [243:242]    [245:244]    [247:246]    [249:248]    [251:250]    [253:252]    [255:254]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000" ,
--		 [1:0]        [3:2] 	   [5:4]        [7:6]        [9:8]        [11:10]      [13:12]      [15:14]
		x"2000044A", x"00100000", x"00000000", x"0000003F", x"00000000", x"31303230", x"392F2F30", x"2D533234", 
--       [17:16]      [19:18]      [21:20]      [23:22]      [25:24]      [27:26]      [29:28]      [31:30]
		x"3020322D", x"20202020", x"00000000", x"41300000", x"3230372E", x"41434541", x"4C4C4849", x"20534553", 
--       [33:32]      [35:34]      [37:36]      [39:38]      [41:40]      [43:42]      [45:44]      [47:46]
		x"41204154", x"534B4449", x"20200D0A", x"20202020", x"20202020", x"20202020", x"20202020", x"80012020", 
--       [49:48]      [51:50]      [53:52]      [55:54]      [57:56]      [59:58]      [61:60]      [63:62]
		x"0F000000", x"02004000", x"00070200", x"00102000", x"0000003F", x"0101007E", x"007E0000", x"04070000", 
--       [65:64]      [67:66]      [69:68]      [71:70]      [73:72]      [75:74]      [77:76]      [79:78]
		x"00780003", x"00780078", x"00000078", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [81:80]      [83:82]      [85:84]      [87:86]      [89:88]      [91:90]      [93:92]      [95:94]
		x"000000FE", x"44000000", x"00004000", x"40000400", x"0000203F", x"00000000", x"00000000", x"00000000", 
--       [97:96]      [99:98]      [101:100]    [103:102]    [105:104]    [107:106]    [109:108]    [111:110]
		x"00000000", x"00000000", x"007E0000", x"00000000", x"00000000", x"00004000", x"00000000", x"00000000", 
--       [113:112]    [115:114]    [117:116]    [119:118]    [121:120]    [123:122]    [125:124]    [127:126]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [129:128]    [131:130]    [133:132]    [135:134]    [137:136]    [139:138]    [141:140]    [143:142]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [145:144]    [147:146]    [149:148]    [151:150]    [153:152]    [155:154]    [157:156]    [159:158]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [161:160]    [163:162]    [165:164]    [167:166]    [169:168]    [171:170]    [173:172]    [175:174]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [177:176]    [179:178]    [181:180]    [183:182]    [185:184]    [187:186]    [189:188]    [191:190]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [193:192]    [195:194]    [197:196]    [199:198]    [201:200]    [203:202]    [205:204]    [207:206]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [209:208]    [211:210]    [213:212]    [215:214]    [217:216]    [219:218]    [221:220]    [223:222]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [225:224]    [227:226]    [229:228]    [231:230]    [233:232]    [235:234]    [237:236]    [239:238]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [241:240]    [243:242]    [245:244]    [247:246]    [249:248]    [251:250]    [253:252]    [255:254]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000" ,
--		 [1:0]        [3:2] 	   [5:4]        [7:6]        [9:8]        [11:10]      [13:12]      [15:14]
		x"2000044A", x"00100000", x"00000000", x"0000003F", x"00000000", x"31303230", x"392F2F30", x"2D533234", 
--       [17:16]      [19:18]      [21:20]      [23:22]      [25:24]      [27:26]      [29:28]      [31:30]
		x"3020322D", x"20202020", x"00000000", x"41300000", x"3230372E", x"41434541", x"4C4C4849", x"20534553", 
--       [33:32]      [35:34]      [37:36]      [39:38]      [41:40]      [43:42]      [45:44]      [47:46]
		x"41204154", x"534B4449", x"20200D0A", x"20202020", x"20202020", x"20202020", x"20202020", x"80012020", 
--       [49:48]      [51:50]      [53:52]      [55:54]      [57:56]      [59:58]      [61:60]      [63:62]
		x"0F000000", x"02004000", x"00070200", x"00102000", x"0000003F", x"0101007E", x"007E0000", x"04070000", 
--       [65:64]      [67:66]      [69:68]      [71:70]      [73:72]      [75:74]      [77:76]      [79:78]
		x"00780003", x"00780078", x"00000078", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [81:80]      [83:82]      [85:84]      [87:86]      [89:88]      [91:90]      [93:92]      [95:94]
		x"000000FE", x"44000000", x"00004000", x"40000400", x"0000203F", x"00000000", x"00000000", x"00000000", 
--       [97:96]      [99:98]      [101:100]    [103:102]    [105:104]    [107:106]    [109:108]    [111:110]
		x"00000000", x"00000000", x"007E0000", x"00000000", x"00000000", x"00004000", x"00000000", x"00000000", 
--       [113:112]    [115:114]    [117:116]    [119:118]    [121:120]    [123:122]    [125:124]    [127:126]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [129:128]    [131:130]    [133:132]    [135:134]    [137:136]    [139:138]    [141:140]    [143:142]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [145:144]    [147:146]    [149:148]    [151:150]    [153:152]    [155:154]    [157:156]    [159:158]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [161:160]    [163:162]    [165:164]    [167:166]    [169:168]    [171:170]    [173:172]    [175:174]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [177:176]    [179:178]    [181:180]    [183:182]    [185:184]    [187:186]    [189:188]    [191:190]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [193:192]    [195:194]    [197:196]    [199:198]    [201:200]    [203:202]    [205:204]    [207:206]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [209:208]    [211:210]    [213:212]    [215:214]    [217:216]    [219:218]    [221:220]    [223:222]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [225:224]    [227:226]    [229:228]    [231:230]    [233:232]    [235:234]    [237:236]    [239:238]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", 
--       [241:240]    [243:242]    [245:244]    [247:246]    [249:248]    [251:250]    [253:252]    [255:254]
		x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000", x"00000000" 		
	);

	-- CountWrEn 
	signal rCntWrEnRst 		:   STD_LOGIC;
    signal rCntWrEnEn 		:   STD_LOGIC;
	signal rCntWrEn			:  	STD_LOGIC_VECTOR (22 downto 0);
	signal rWrLimit			:  	STD_LOGIC_VECTOR (22 downto 0);
	
	-- CountFmt
	signal rCntFmtRst 		:   STD_LOGIC;
    signal rCntFmtEn 		:   STD_LOGIC;	
	signal rCntFmt			:  	STD_LOGIC_VECTOR (4 downto 0);
	
	
	
begin

----------------------------------------------------------------------------------
-- Output assignment
----------------------------------------------------------------------------------
	
	-- SataUser interface
    SataCmdReq 		<= rSataCmdReq;
    SataCmd 		<= rSataCmd;
    SataAddr 		<= rSataAddr;
    SataLength 		<= rSataLength;
	
	-- SataFifo interface
	WrFfWrEn 		<= rWrFfWrEn;
	WrFfWrData		<= rWrFfWrData;

----------------------------------------------------------------------------------
-- DFF
----------------------------------------------------------------------------------
	
--FmtCtrl State machine
	u_rFmtState : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rFmtState <= stIdle;
		elsif ( rising_edge(Clk) ) then
			case ( rFmtState ) is
			
				when stIdle 	=> 
					if ( FmtReq = '1' ) then
						rFmtState 		<= stWrPrep;
					else
						rFmtState		<= stIdle;
					end if;
					
				when stWrPrep	=> 
					if ( SataBusy = '0' ) then
						rFmtState 		<= stWrReq;
					else
						rFmtState 		<= stWrPrep;
					end if;
					
				when stWrReq	=> 
					if ( SataBusy = '1' ) then
						rFmtState 		<= stWrStream;
					else
						rFmtState 		<= stWrReq;
					end if;
					
				when stWrStream =>
					if ( rCntWrEn=rWrLimit ) then
						rFmtState 		<= stWrWt;
					else
						rFmtState 		<= stWrStream;
					end if;
					
				when stWrWt		=> 
					if ( SataBusy = '0' ) then
						rFmtState 		<= stCntFmtChk;
					else
						rFmtState 		<= stWrWt;
					end if;
					
				when stCntFmtChk => 
					if ( rCntFmt = '1'&x"5" ) then
						rFmtState 		<= stEnd;
					else
						rFmtState 		<= stWrPrep;
					end if;

				when stEnd		=> null;
				
				--play safe with other possible states
				when others		=> 
					rFmtState		<= stIdle; 
				
			end case;
		end if;
	End Process u_rFmtState;
	
--SataUser interface
	u_rSataCmdReq : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rSataCmdReq <= '0';
		elsif ( rising_edge(Clk) ) then
			if ( SataBusy='1' ) then
				rSataCmdReq <= '0';
			elsif ( rFmtState=stWrReq ) then
				rSataCmdReq <= '1';
			else
				rSataCmdReq <= '0';
			end if;
		end if;
	End Process u_rSataCmdReq;
	
	u_rSataCmd : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rSataCmd <= '0';
		elsif ( rising_edge(Clk) ) then
			rSataCmd <= '0';
		end if;
	End Process u_rSataCmd;
	
	u_rSataAddr : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rSataAddr <= (OTHERS=>'0');
		elsif ( rising_edge(Clk) ) then
			case rCntFmt is
				when (('0')&x"0")|(('0')&x"1") |(('0')&x"2")|(('0')&x"3")|
				(('0')&x"4")|(('0')&x"5")|(('0')&x"6")|(('0')&x"7")|(('0')&x"8")|
				(('0')&x"9")|(('0')&x"A")|(('0')&x"B")| (('0')&x"C")|(('0')&x"D")	
												=>  rSataAddr <= (OTHERS=>'0')&rCntFmt(3 downto 0)&x"0000"; 		--  0 20 BU.
				when ('0')&x"E"					=> 	rSataAddr <= (OTHERS=>'0');									--  PrtnTbRAM
				when ('0')&x"F" 			 	=> 	rSataAddr <= (OTHERS=>'0')&x"8000";							--  PrtnBtRAM
				when ('1')&x"0" 				=>  rSataAddr <= (OTHERS=>'0')&x"8006";							--  PrtnBtRAM Backup
				when ('1')&x"1" 				=>  rSataAddr <= (OTHERS=>'0')&x"8001";							--  FSInfoRAM
				when ('1')&x"2" 				=>  rSataAddr <= (OTHERS=>'0')&x"8007";							--  FSInfoRAM Backup
				when ('1')&x"3" 				=>  rSataAddr <= (OTHERS=>'0')&x"10000";						--  sector#0 of FAT1
				when ('1')&x"4" 				=>  rSataAddr <= (OTHERS=>'0')&x"50000";						--  sector#0 of FAT2
				when others						=> 	rSataAddr <= (OTHERS=>'0');
			end case;
		end if;
	End Process u_rSataAddr;
	
	u_rSataLength : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rSataLength <= (OTHERS=>'0');
		elsif ( rising_edge(Clk) ) then
			if ( rCntFmt >= x"E" ) then
				rSataLength <= (OTHERS=>'0')&x"10000";
			else
				rSataLength <= (OTHERS=>'0')&'1';
			end if;
		end if;
	End Process u_rSataLength;
	
-- SataFifo interface
	u_rWrFfWrEn : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rWrFfWrEn <= '0';
		elsif ( rising_edge(Clk) ) then
			if ( rFmtState=stWrStream and WrFfAFull='0' ) then 
				rWrFfWrEn <= '1';
			else
				rWrFfWrEn <= '0';
			end if;
		end if;
	End Process u_rWrFfWrEn;
	
	u_rWrFfDataSelect : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rWrFfDataSelect <= '0';
		elsif ( rising_edge(Clk)) then
			if ( rCntFmt >= x"E" ) then
				rWrFfDataSelect <= '1';
			else
				rWrFfDataSelect <= '0';
			end if;
		end if;
	End Process u_rWrFfDataSelect;
	
	u_rWrFfWrData : Process(Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rWrFfWrData <= (OTHERS=>'0');
		elsif ( rising_edge(Clk) ) then
			if ( rWrFfDataSelect='1' ) then
				rWrFfWrData <= rRAMDout;
			else
				rWrFfWrData <= (OTHERS=>'0');
			end if;
		end if;
	End Process u_rWrFfWrData;

-- Ram
	u_rRAMOffset : Process(Rst,Clk) Is
	Begin
		if ( Rst='1' ) then
			rRAMOffset <= (OTHERS=>'0');
		elsif ( rising_edge(Clk) ) then
			case rCntFmt is
				when ('0'&x"F") | ('1'&x"0") => rRAMOffset 	<= '0'&x"80";
				when ('1'&x"1") | ('1'&x"2") =>	rRAMOffset 	<= '1'&x"00";
				when ('1'&x"3") | ('1'&x"4") =>	rRAMOffset 	<= '1'&x"80";
				when others 				 => rRAMOffset 	<= (OTHERS=>'0');
			end case;
		end if;
	End Process u_rRAMOffset;
	
	u_rRAMAddr : Process(Rst,Clk) Is
	Begin
		if ( Rst='1' ) then
			rRAMAddr <= (OTHERS=>'0');
		elsif ( rising_edge(Clk) ) then
			if ( rWrFfWrEn='1' ) then
				rRAMAddr 	<= rRAMOffset + rCntWrEn(8 downto 0)+1;
			else
				rRAMAddr	<= rRAMOffset + rCntWrEn(8 downto 0);
			end if;
		end if;
	End Process u_rRAMAddr;
	
	rRAMWrEn <= '0';
	
	u_rRAMDin : Process(Clk) Is
	Begin
		if ( rising_edge(Clk) ) then
			-- Write process
			if ( rRAMWrEn='1' ) then
				RamMem(conv_integer(rRAMAddr)) <= rRAMDin;
			end if;
		end if;
	End Process u_rRAMDin;
	
	u_rRAMDout : Process(Clk) Is
	Begin
		if ( rising_edge(Clk) ) then
			-- Read process
			rRAMDout	<= RamMem(conv_integer(rRAMAddr));
		end if;
	End Process u_rRAMDout;
	
-- WrEnCounter
	u_rCntWrEnRst : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rCntWrEnRst <= '0';
		elsif ( rising_edge(Clk) ) then
			if ( rFmtState=stWrPrep ) then
				rCntWrEnRst <= '1';
			else
				rCntWrEnRst <= '0';
			end if;
		end if;
	End Process u_rCntWrEnRst;
	
	u_rCntWrEnEn : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rCntWrEnEn <= '0';
		elsif ( rising_edge(Clk) ) then
			if ( rWrFfWrEn='1' ) then
				rCntWrEnEn <= '1';
			else
				rCntWrEnEn <= '0';
			end if;
		end if;
	End Process u_rCntWrEnEn;
	
	u_rCntWrEn : Process (rCntWrEnRst, Clk) Is
	Begin
		if ( rCntWrEnRst='1' ) then
			rCntWrEn <= (OTHERS=>'0') ;
		elsif ( rising_edge(Clk) ) then
			if ( rCntWrEnEn='1') then
				rCntWrEn <= rCntWrEn + 1;
			else
				rCntWrEn <= rCntWrEn;
			end if;
		end if;
	End Process u_rCntWrEn;	
	
	u_rWrLimit : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rWrLimit <= (OTHERS=>'0');
		elsif ( rising_edge(Clk) ) then
			if ( rWrFfDataSelect='1' ) then
				rWrLimit <= (OTHERS=>'0')&x"7E";
			else
				rWrLimit <= (OTHERS=>'0')&x"7FFFFE";
			end if;
		end if;
	End Process u_rWrLimit;
	
--FmtCounter
	u_rCntFmtRst : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rCntFmtRst <= '0';
		elsif ( rising_edge(Clk) ) then
			if ( rFmtState=stIdle ) then
				rCntFmtRst <= '1';
			else
				rCntFmtRst <= '0';
			end if;
		end if;
	End Process u_rCntFmtRst;
	
	u_rCntFmtEn : Process (Rst, Clk) Is
	Begin
		if ( Rst='1' ) then
			rCntFmtEn <= '0';
		elsif ( rising_edge(Clk) ) then
			if ( rFmtState=stCntFmtChk ) then
				rCntFmtRst <= '1';
			else
				rCntFmtRst <= '0';
			end if;
		end if;
	End Process u_rCntFmtEn;	
	
	u_rCntFmt : Process (rCntFmtRst, Clk) Is
	Begin
		if ( rCntFmtRst='1' ) then
			rCntFmt <= (OTHERS=>'0') ;
		elsif ( rising_edge(Clk) ) then
			if ( rCntFmtEn='1') then
				rCntFmt <= rCntFmt + 1;
			else
				rCntFmt <= rCntFmt;
			end if;
		end if;
	End Process u_rCntFmt;	


end Behavioral;

